
                /*********************************************
                **                                          **
                **                                          **
                **                   th.C                   **
                **                                          **
                **                                          **
                *********************************************/
                /*********************************************
                **                                          **
                **         Author Jean-Marc Adamo           **
                **       Copyright (C) 1997-2008 JMA        **
                *********************************************/


/*
Threads
This is to illustrate concurrency. The program is to 
be run on only one node. If several nodes are used, 
the local instances of the code are independently 
run from one another (no inter-processor communication). 
The Root_thread instance creates and runs two instances 
of the Sthread class that in turn recursively run two 
instances of the same class. 
*/

#include "arch.h"
#include "A.utilities"
#include "limits.h"

//user program

class Proc: public S_Thread{

   public:
        int pid;
        int step;

        Proc(int p, int s): S_Thread((Smf0_ptr)&Proc::body)
        {pid = p; step = s;}

        void body()
          {
               fprintf(Sdf::trace, "node %d, in proc %d before loop at step %d\n",
                       Sdf::PROC_ID, pid, step);
               fflush(Sdf::trace);


               int i;

               for(i = 0; i < 20; i++)
               {
                   fprintf(Sdf::trace, "node %d, proc %d in for loop, i = %d\n",
                                Sdf::PROC_ID, pid, i);
                   reschedule();
               }

               fprintf(Sdf::trace, "node %d, in proc %d after for loop at step %d\n",
                       Sdf::PROC_ID, pid, step);
               fflush(Sdf::trace);


               if(step<1)
              {
                   Proc *proc1 = new Proc(pid*10 + 1, step+1);
                   Proc *proc2 = new Proc(pid*10 + 2, step+1);


                   S_Thread *proc_tabl[2] = {proc1, proc2};
                   int pri[2] = {1, 1};
                   par(2, proc_tabl, pri);

                   delete proc1;
                   delete proc2;
               }

               fprintf(Sdf::trace, "on node %d, proc %d the end at step %d\n",
                        Sdf::PROC_ID, pid, step);
               fflush(Sdf::trace);
        }
};

class Root_proc: public Thread{

   public:

        Root_proc()
                : Thread((Tmf0_ptr)&Root_proc::body){}

        void body()
      {
                fprintf(Sdf::trace, "node %d, in Root_proc::body1\n", Sdf::PROC_ID);
                fflush(Sdf::trace);


                Proc *proc1 = new Proc(1, 0);

                Proc *proc2 = new Proc(2, 0);


                fprintf(Sdf::trace, "node %d, in Root_proc::body2\n", Sdf::PROC_ID);
                fflush(Sdf::trace);


                S_Thread *proc_tabl[2] = {proc1, proc2};
                int pri[2] = {1, 1};
                par(2, proc_tabl, pri);


                fprintf(Sdf::trace, "node %d, in Root_proc::body4\n", Sdf::PROC_ID);
                fflush(Sdf::trace);


                delete proc1;
                delete proc2;
        }
};
//end of user program
MAIN(Root_proc, Sdf::empty, Sdf::empty, Sdf::empty, argc, argv)


